package me.acomma.groot.application.user;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import me.acomma.groot.domain.role.RoleRepository;
import me.acomma.groot.domain.user.User;
import me.acomma.groot.domain.user.UserId;
import me.acomma.groot.domain.user.UserRepository;
import me.acomma.groot.infrastructure.Pagination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;

@Component
public class UserApplicationService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private UserAssembler userAssembler;

    public UserData get(Long userId) {
        User user = userRepository.get(UserId.of(userId));
        return userAssembler.toUserData(user);
    }

    @Transactional(rollbackFor = {Exception.class})
    public void create(CreateUserCommand command) {
        User user = new User();
        user.setUserId(userRepository.nextId());
        user.setUsername(command.getUsername());
        user.setPassword(command.getPassword());
        user.setName(command.getName());
        user.setGender(command.getGender());
        user.setAge(command.getAge());
        user.setBirthday(command.getBirthday());
        user.setHeight(command.getHeight());
        user.setWeight(command.getWeight());
        userRepository.add(user);
    }

    @Transactional(rollbackFor = {Exception.class})
    public void modify(ModifyUserCommand command) {
        User user = userRepository.get(UserId.of(command.getUserId()));
        if (Objects.isNull(user)) {
            throw new IllegalStateException("用户不存在");
        }
        user.setUsername(command.getUsername());
        user.setPassword(command.getPassword());
        user.setName(command.getName());
        user.setGender(command.getGender());
        user.setAge(command.getAge());
        user.setBirthday(command.getBirthday());
        user.setHeight(command.getHeight());
        user.setWeight(command.getWeight());
        userRepository.update(user);
    }

    @Transactional(rollbackFor = {Exception.class})
    public void remove(Long userId) {
        User user = userRepository.get(UserId.of(userId));
        if (Objects.isNull(user)) {
            return;
        }
        long count = roleRepository.countByUserId(UserId.of(userId));
        if (count > 0) {
            throw new IllegalStateException("请先移除用户的角色信息");
        }
        userRepository.remove(UserId.of(userId));
    }

    public Pagination<UserData> pageQuery(PageQueryUserCommand command) {
        User user = userAssembler.toUser(command);
        Page<User> page = PageHelper.startPage(command.getPageNumber(), command.getPageSize());
        List<User> users = userRepository.pageQuery(user);
        return new Pagination<>(command.getPageNumber(), command.getPageSize(), page.getTotal(), userAssembler.toUserDataList(users));
    }

    @Transactional(rollbackFor = {Exception.class})
    public void assignRole(AssignRoleCommand command) {
        userRepository.removeUserRoleByUserId(new UserId(command.getUserId()));
        if (!CollectionUtils.isEmpty(command.getRoleIds())) {
            userRepository.addUserRole(command.getUserId(), command.getRoleIds());
        }
    }
}
